/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package socof.wget;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 *
 * @author Carlos Pinheiro
 */
public class ParsersLauncher extends Thread
{
    private static final int WAIT_TIME = 1000;
    private static final int PARSERS_LIMIT = 10;
    
    private ResizeableSemaphore maxParsers = new ResizeableSemaphore(0);
    private ExecutorService tpParsers = Executors.newCachedThreadPool();
    private double maxCpuUsage;
    private int parsersLimit = PARSERS_LIMIT;
    
    private static ParsersLauncher lb = new ParsersLauncher();

    private ParsersLauncher()
    {
    }

    public static ParsersLauncher getInstance()
    {
        return ParsersLauncher.lb;
    }
    
    public synchronized void setMaxCpuUsage (double maxCpuUsage)
    {
        this.maxCpuUsage = maxCpuUsage;
    }
    
    public synchronized double getMaxCpuUsage ()
    {
        return this.maxCpuUsage;
    }
    
    public synchronized void setParsersLimit (int parsersLimit)
    {
        this.parsersLimit = parsersLimit;
    }

    @Override
    public void run()
    {
        // Starts parsers controller
        ParsersController.getInstance().start();
        
        try
        {
            tpParsers = Executors.newCachedThreadPool();
            while (!isInterrupted())
            {
                if (ToParseQueue.getInstance().isEmpty())
                {
                    Thread.sleep(WAIT_TIME);
                    continue;
                }
                
                Runnable parser = new ExecutorParser(maxParsers);
                tpParsers.execute(parser);
            }
        }
        catch (InterruptedException ex)
        {            
        }
        finally
        {
            processInterruption();
        }
    }
    
    private void processInterruption()
    {            
        try
        {
            ParsersController.getInstance().interrupt();
            
            tpParsers.shutdown();
            tpParsers.awaitTermination(10, TimeUnit.SECONDS);
        }
        catch (InterruptedException ex)
        {
        }
    }
    
    public void decreaseParsers()
    {
        if (maxParsers.getTotalPermits() > 1)
            maxParsers.removePermit();
    }
    
    public void increaseParsers()
    {
        if (maxParsers.getTotalPermits() < parsersLimit)
            maxParsers.addPermit();
    }
    
    public void removeAllParsers()
    {
        maxParsers.removeAllPermits();
    }
    
    public int getNumberOfParsers()
    {
        return maxParsers.getTotalPermits();
    }
}
